// app/service/invitation_service.js
'use strict';

const Service = require('egg').Service;
const crypto = require('crypto');

class InvitationService extends Service {
  // 生成邀请链接
  async generateInvitation(organizationId, email, role, invitedBy) {
    const { ctx } = this;
    
    try {
      // 生成唯一的邀请令牌
      const token = crypto.randomBytes(32).toString('hex');
      
      // 设置7天后过期
      const expiresAt = new Date();
      expiresAt.setDate(expiresAt.getDate() + 7);
      
      // 创建邀请记录
      const invitation = await ctx.model.InvitationModel.create({
        organizationId,
        email,
        role,
        token,
        expiresAt,
        invitedBy
      });
      
      // 生成邀请链接
      const inviteUrl = `${ctx.request.origin}/accept-invitation?token=${token}`;
      
      return {
        success: true,
        data: {
          invitation,
          inviteUrl
        }
      };
    } catch (error) {
      ctx.logger.error('生成邀请失败:', error);
      return {
        success: false,
        message: `生成邀请失败: ${error.message}`
      };
    }
  }
  
  // 验证邀请令牌
  async validateInvitationToken(token) {
    const { ctx } = this;
    
    try {
      // 查找邀请记录
      const invitation = await ctx.model.InvitationModel.findOne({
        where: { token },
        include: [
          {
            model: ctx.model.OrganizationModel,
            as: 'organization'
          }
        ]
      });
      
      if (!invitation) {
        return {
          success: false,
          message: '邀请链接无效'
        };
      }
      
      // 检查是否已接受
      if (invitation.status === 'accepted') {
        return {
          success: false,
          message: '邀请已被接受'
        };
      }
      
      // 检查是否过期
      if (invitation.expiresAt < new Date()) {
        // 更新状态为已过期
        await invitation.update({ status: 'expired' });
        return {
          success: false,
          message: '邀请链接已过期'
        };
      }
      
      return {
        success: true,
        data: invitation
      };
    } catch (error) {
      ctx.logger.error('验证邀请令牌失败:', error);
      return {
        success: false,
        message: `验证邀请令牌失败: ${error.message}`
      };
    }
  }
  
  // 接受邀请
  async acceptInvitation(token, userId) {
    const { ctx } = this;
    
    try {
      // 验证邀请令牌
      const validation = await this.validateInvitationToken(token);
      if (!validation.success) {
        return validation;
      }
      
      const invitation = validation.data;
      
      // 检查用户邮箱是否匹配
      const user = await ctx.model.UserModel.findByPk(userId);
      if (!user || user.email !== invitation.email) {
        return {
          success: false,
          message: '邮箱不匹配，无法接受邀请'
        };
      }
      
      // 添加用户到组织
      await ctx.model.UserOrganizationModel.findOrCreate({
        where: { 
          userId: user.id, 
          organizationId: invitation.organizationId 
        },
        defaults: { 
          userId: user.id, 
          organizationId: invitation.organizationId,
          role: invitation.role
        }
      });
      
      // 更新邀请状态为已接受
      await invitation.update({ status: 'accepted' });
      
      return {
        success: true,
        message: '邀请接受成功'
      };
    } catch (error) {
      ctx.logger.error('接受邀请失败:', error);
      return {
        success: false,
        message: `接受邀请失败: ${error.message}`
      };
    }
  }
  
  // 获取组织的邀请列表
  async getOrganizationInvitations(organizationId) {
    const { ctx } = this;
    
    try {
      const invitations = await ctx.model.InvitationModel.findAll({
        where: { organizationId },
        include: [
          {
            model: ctx.model.UserModel,
            as: 'inviter',
            attributes: ['id', 'name', 'email']
          }
        ],
        order: [['createdAt', 'DESC']]
      });
      
      return {
        success: true,
        data: invitations
      };
    } catch (error) {
      ctx.logger.error('获取组织邀请列表失败:', error);
      return {
        success: false,
        message: `获取组织邀请列表失败: ${error.message}`
      };
    }
  }
  
  // 撤销邀请
  async revokeInvitation(id) {
    const { ctx } = this;
    
    try {
      const invitation = await ctx.model.InvitationModel.findByPk(id);
      if (!invitation) {
        return {
          success: false,
          message: '邀请记录不存在'
        };
      }
      
      await invitation.destroy();
      
      return {
        success: true,
        message: '邀请已撤销'
      };
    } catch (error) {
      ctx.logger.error('撤销邀请失败:', error);
      return {
        success: false,
        message: `撤销邀请失败: ${error.message}`
      };
    }
  }
}

module.exports = InvitationService;